import { IADAble, ADConfig, AdFrom, ADType, ADEvent } from "../IADAble";

export class WXAd extends IADAble {
    protected _wx:any;
    private _tempBanner:any;
    private _tempInterstitial:any;

    init(type: string, config: ADConfig): IADAble {
        this._wx = window['wx'];
        return super.init(type, config);
    }

    loadBanner(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex: number=0): void {
        if(this._tempBanner){
            this._tempBanner.destroy();
            this._tempBanner = null;
        }
        this._tempBanner = this._wx.createBannerAd({
            adUnitId:this._config.bannerUnitIds[unitIdIndex]
        })
        let onLoad = ()=>{
            this._tempBanner['___tempId'] = this._config.bannerUnitIds[unitIdIndex];
            this._tempBanner.offLoad(onLoad);
            this._tempBanner.offError(onError);
            onSuccess && onSuccess.apply(caller);
        }
        this._tempBanner.onLoad(onLoad);

        let onError = (error)=>{
            this._tempBanner.offLoad(onLoad);
            this._tempBanner.offError(onError);
            if(++unitIdIndex >= this._config.bannerUnitIds.length){
                onFail && onFail.apply(caller, error);
            }else{
                this._tempBanner.destroy();
                this._tempBanner = null;
                this.loadBanner(from, caller, onSuccess, onFail, unitIdIndex);
            }
        }
        this._tempBanner.onError(onError);
    }

    showBanner(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex: number=0): void {
        let show = ()=>{
            this._tempBanner.show().then(()=>{
                onSuccess && onSuccess.apply(caller);
            }).catch((error)=>{
                if(++unitIdIndex >= this._config.bannerUnitIds.length){
                    onFail && onFail.apply(caller, error);
                }else{
                    this._tempBanner.destroy();
                    this._tempBanner = null;
                    this.showBanner(from, caller, onSuccess, onFail, unitIdIndex);
                }
            })
        }
        if(!this._tempBanner || this._tempBanner['___tempId'] != this._config.bannerUnitIds[unitIdIndex]){
            this.loadBanner(from, this, ()=>{
                show();
            }, (error)=>{
                onFail && onFail.apply(caller, error);
            }, unitIdIndex);
        }else{
            show();
        }
    }

    hideBanner(): void {
        if(this._tempBanner){
            this._tempBanner.hide();
            this._tempBanner.destroy();
            this._tempBanner = null;
        }
    }

    loadInterstitial(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex: number=0): void {
        if(this._tempInterstitial){
            this._tempInterstitial.destroy();
            this._tempInterstitial = null;
        }
        this._tempInterstitial = this._wx.createInterstitialAd({adUnitId:this._config.interstitialUnitIds[unitIdIndex]});
        from && this._report(ADType.INTERSTITIAL, ADEvent.LOAD, from);
        this._tempInterstitial.load().then(()=>{
            this._tempInterstitial['___tempId'] = this._config.interstitialUnitIds[unitIdIndex];
            from && this._report(ADType.INTERSTITIAL, ADEvent.LOAD_COMPLETE, from);
            onSuccess && onSuccess.apply(caller);
        }).catch((error:{errCode:number, errMsg:string})=>{
            if(++unitIdIndex >= this._config.interstitialUnitIds.length){
                from && this._report(ADType.INTERSTITIAL, ADEvent.LOAD_FAIL, from, error.errMsg);
                onFail && onFail.apply(caller, error);
            }else{
                this.loadInterstitial(from, caller, onSuccess, onFail, unitIdIndex);
            }
        });
    }

    showInterstitial(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex: number=0): void {
        let show = ()=>{
            this._report(ADType.INTERSTITIAL, ADEvent.SHOW, from);
            this._tempInterstitial.show().then(()=>{
                this._report(ADType.INTERSTITIAL, ADEvent.SHOW_COMPLETE, from);
                onSuccess && onSuccess.apply(caller);
            }).catch((error:{errCode:number, errMsg:string})=>{
                if(++unitIdIndex >= this._config.interstitialUnitIds.length){
                    this._report(ADType.INTERSTITIAL, ADEvent.SHOW_FAIL, from, error.errMsg);
                    onFail && onFail.apply(caller, error);
                }else{
                    this._tempInterstitial.destroy();
                    this._tempInterstitial = null;
                    this.showInterstitial(from, caller, onSuccess, onFail, unitIdIndex);
                }
            });
        }
        if(!this._tempInterstitial || this._tempInterstitial['___tempId'] != this._config.interstitialUnitIds[unitIdIndex]){
            this.loadInterstitial(from, this, ()=>{
                show();
            }, (error:{errCode:number, errMsg:string})=>{
                onFail && onFail.apply(caller, error);
            }, unitIdIndex);
        }else{
            show();
        }
    }

    showRewardVideo(from:AdFrom, caller?: any, onSuccess?: Function, onFail?: Function, unitIdIndex: number=0): void {
        this._report(ADType.REWARD_VIDEO, ADEvent.SHOW, from);
        let videoAd = this._wx.createRewardedVideoAd({adUnitId:this._config.rewardVideoUnitIds[unitIdIndex]});
        let onClose = (result:{isEnded:boolean, count:number})=>{
            videoAd.offClose(onClose);
            // videoAd.destroy();
            if(result.isEnded){
                this._report(ADType.REWARD_VIDEO, ADEvent.SHOW_COMPLETE, from);
                onSuccess && onSuccess.apply(caller);
            }else{
                this._report(ADType.REWARD_VIDEO, ADEvent.CLOSE_BY_USER, from);
                onFail && onFail.apply(caller);
            }
        }
        videoAd.onClose(onClose);
        videoAd.load().then(()=>{
            videoAd.show().catch((error:{errCode:number, errMsg:string})=>{
                if(++unitIdIndex >= this._config.rewardVideoUnitIds.length){
                    this._report(ADType.REWARD_VIDEO, ADEvent.SHOW_FAIL, from, error.errMsg);
                    onFail && onFail.apply(caller, error);
                }else{
                    this.showRewardVideo(from, caller, onSuccess, onFail, unitIdIndex);
                }
            })
        }).catch((error:{errCode:number, errMsg:string})=>{
            if(++unitIdIndex >= this._config.rewardVideoUnitIds.length){
                this._report(ADType.REWARD_VIDEO, ADEvent.LOAD_FAIL, from, error.errMsg);
                onFail && onFail.apply(caller, error);
            }else{
                this.showRewardVideo(from, caller, onSuccess, onFail, unitIdIndex);
            }
        });
    }
}
